import java.lang.annotation.*;

public class RepeatableAnnotation {

    static class JDK8Before {
        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        public @interface FilterPath {
            String[] value();
        }

        //使用
        @FilterPath({"/update", "/add"})
        public class A {
        }
    }

    static class JDK8After {
        /**
         * Created by zejian on 2017/5/20.
         * Blog : http://blog.csdn.net/javazejian [原文地址,请尊重原创]
         */
        //使用Java8新增@Repeatable原注解
        @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
        @Retention(RetentionPolicy.RUNTIME)
        @Repeatable(FilterPaths.class)//参数指明接收的注解class
        public @interface FilterPath {
            String value();
        }

        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        @interface FilterPaths {
            FilterPath[] value();
        }

        //使用案例
        @FilterPath("/web/update")
        @FilterPath("/web/add")
        @FilterPath("/web/delete")
        class AA {
        }
    }

    public static class JDK8AfterTest {
        /**
         * Created by zejian on 2017/5/20.
         * Blog : http://blog.csdn.net/javazejian [原文地址,请尊重原创]
         */
        //使用Java8新增@Repeatable原注解
        @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
        @Retention(RetentionPolicy.RUNTIME)
        @Repeatable(FilterPaths.class)
        public @interface FilterPath {
            String value();
        }


        @Target(ElementType.TYPE)
        @Retention(RetentionPolicy.RUNTIME)
        @interface FilterPaths {
            FilterPath[] value();
        }

        @FilterPath("/web/list")
        class CC {
        }

        //使用案例
        @FilterPath("/web/update")
        @FilterPath("/web/add")
        @FilterPath("/web/delete")
        class AA extends CC {
            public void Test(String[] args) {

                Class<?> clazz = AA.class;
                //通过getAnnotationsByType方法获取所有重复注解
                FilterPath[] annotationsByType = clazz.getAnnotationsByType(FilterPath.class);
                FilterPath[] annotationsByType2 = clazz.getDeclaredAnnotationsByType(FilterPath.class);
                if (annotationsByType != null) {
                    for (FilterPath filter : annotationsByType) {
                        System.out.println("1:" + filter.value());
                    }
                }

                System.out.println("-----------------");

                if (annotationsByType2 != null) {
                    for (FilterPath filter : annotationsByType2) {
                        System.out.println("2:" + filter.value());
                    }
                }
                System.out.println("使用getAnnotation的结果:" + clazz.getAnnotation(FilterPath.class));
            }
        }
    }
}

class MyRepeatableAnnotation {
    @Documented
    //@Target({ElementType.TYPE})
    @Target({ElementType.TYPE,ElementType.METHOD,ElementType.CONSTRUCTOR})/*这个地方这样写了会导致编译不通过*/
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Names.class)
    public @interface Name{}

    @Documented
    @Target({ElementType.TYPE,ElementType.METHOD,ElementType.CONSTRUCTOR})/*这个地方这样写了会导致编译不通过*/
    //@Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public  @interface Names{
        Name [] value();
    }
}
